<template>
  <div id="box" :style="'width:' + width + 'px'" :class="{ circle }">
    <div class="bgBox" :class="{ circle }"></div>
    <div class="tip">{{ initialtext }}</div>
    <div class="slider" :class="{ circle }">
      <i v-show="!isSuccess" class="el-icon-d-arrow-right"></i>
      <i v-show="isSuccess" class="el-icon-check"></i>
    </div>
  </div>
</template>

<script>
export default {
  name: "SlideUnlock",
  mounted() {
    // 获取元素方法
    function $(selector) {
      return document.querySelector(selector);
    }

    // 获取所有需要的dom
    let box = $("#box"),
      bgBox = $(".bgBox"), //背景色
      tip = $(".tip"), //文本
      slider = $(".slider"), //滑块
      // icon = $(".slider>i"),
      successMoveDistance = box.offsetWidth - slider.offsetWidth, //解锁需要滑动的距离
      downX; //用于存放鼠标按下时的位置

    // 添加鼠标事件
    slider.onmousedown = slider.ontouchstart = (e) => {
      bgBox.style.transition = "";
      slider.style.transition = "";

      e = e || window.Event;
      downX = e.clientX ? e.clientX : e.changedTouches[0].clientX;

      if (!this.isSuccess) {
        document.onmousemove = document.ontouchmove = (e) => {
          e = e || window.event;
          var moveX = e.clientX ? e.clientX : e.changedTouches[0].clientX;

          var offsetX = (() => {
            let offset = moveX - downX;
            if (offset < 0) {
              offset = 0;
            } else if (offset > successMoveDistance) {
              offset = successMoveDistance;
            }
            return offset;
          })();

          bgBox.style.width = offsetX + 40 + "px";
          slider.style.left = offsetX + "px";

          if (offsetX == successMoveDistance) {
            //success();
            this.isSuccess = true;
            tip.innerHTML = this.successtext;
            bgBox.style.backgroundColor = "rgba(144, 238, 144, 0.5)";
            //滑动成功时，移除鼠标按下事件和鼠标移动事件
            slider.onmousedown = null;
            document.onmousemove = null;
            //移除移动端事件
            document.ontouchstart = null;
            document.ontouchmove = null;
          }
          //如果不设置滑块滑动时会出现问题（目前还不知道为什么）
          e.preventDefault();
        };

        document.onmouseup = document.ontouchend = () => {
          if (!this.isSuccess) {
            bgBox.style.width = "0px";
            slider.style.left = "0px";
            bgBox.style.transition = "width 0.2s linear";
            slider.style.transition = "left 0.2s linear";
          }
          document.onmousemove = null;
          document.onmouseup = null;
          //移除移动端事件
          document.ontouchmove = null;
          document.ontouchend = null;
        };
      }
    };
  },
  data() {
    return {
      isSuccess: false,
    };
  },
  props: {
    initialtext: {
      type: String,
      default: () => {
        return "滑动验证";
      },
    },
    successtext: {
      type: String,
      default: () => {
        return "验证成功";
      },
    },
    width: {
      type: Number,
      default: () => {
        return 300;
      },
    },
    circle: {
      type: Boolean,
      default: () => {
        return false;
      },
    },
  },
  watch: {
    isSuccess(newValue) {
      if (newValue) {
        this.$emit("update:isSuccess", newValue);
      }
    },
  },
};
</script>

<style lang="scss">
* {
  touch-action: pan-y;
  #box {
    position: relative;
    height: 40px;
    margin: 0 auto;
    border-radius: 3px;
    // margin-top: 10px;
    background-color: #e8e8e8a7;
    box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
    .bgBox {
      position: absolute;
      width: 40px;
      height: 40px;
      background-color: rgba(173, 216, 230, 0.9);
    }
    .tip {
      position: absolute;
      width: 100%;
      height: 40px;
      line-height: 40px;
      font-size: 14px;
      color: #000;
      text-align: center;
    }
    .slider {
      position: absolute;
      left: 0;
      top: 0;
      width: 40px;
      height: 40px;
      border: 1px solid #ccc;
      background: #fff;
      text-align: center;
      cursor: move;
      i {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
    }
  }
  .circle {
    border-radius: 20px;
  }
}
</style>
